Skip to content

refactor(bootstrap): split into configure/up, add state.json - #6

Open
BKJN1 wants to merge 3 commits into
mainfrom
feat/configure-up-split
Open

refactor(bootstrap): split into configure/up, add state.json#6
BKJN1 wants to merge 3 commits into
mainfrom
feat/configure-up-split

Conversation

@BKJN1

@BKJN1 BKJN1 commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

bootstrap used to be one function: check the machine, generate configs,
start everything — no way to stop in between. That's fine locally, where
the CLI owns the database it just created, but won't work for a real
server, where the database already exists and "change the schema" has to
be a decision someone makes on purpose, not a side effect of starting a
service. Groundwork for a separate versola migrate step ahead of
deploying to the VPS.

  • internal/deploy: split into Configure (prerequisite checks, runs
    versola-tools, writes the compose file) and Up (starts the stack,
    waits for readiness). bootstrap still calls both in sequence, so
    external behavior is unchanged — this is a pure refactor, verified by a
    local deployment behaving exactly as before.
  • internal/state: replaces the old bare version file with state.json
    (target, version, configuredAt, migratedAt, bundleDir), so later commands
    (status/migrate/up) can tell what's actually been deployed and how far
    along it got, instead of inferring it from which files happen to exist.
    Deployments made by earlier CLI builds still read correctly (loadLegacy).
  • Each configure run now gets its own bundle-<timestamp> directory
    instead of reusing one fixed path — works around a Docker Desktop bug
    where bind-mounting a wiped-and-recreated path can make a container's own
    cp fail with "File exists" for a file that doesn't exist.
  • internal/docker: Run/Cmd extracted out of bootstrap.go, reused by
    uninstall.go.

No behavior change for versola bootstrap local — verified locally.

- internal/deploy: Configure (checks + versola-tools + compose.yml) and
  Up (start stack, wait readiness) as separate steps, bootstrap.local
  calls both in sequence -- external behavior unchanged.
- internal/state: replace bare 'version' file with state.json
  (target/version/configuredAt/migratedAt), keep reading the old format
  for deployments made by earlier CLI builds.
- each configure run gets its own bundle-<timestamp> directory instead
  of reusing one fixed path -- works around a Docker Desktop bug where
  bind-mounting a wiped-and-recreated path can make cp fail with
  'File exists' for a file that doesn't exist.
- internal/docker: docker.Run/Cmd extracted out of bootstrap.go, reused
  by uninstall.go.
@augmentcode

augmentcode Bot commented Aug 15, 2026

Copy link
Copy Markdown
🤖 Augment PR Summary

Summary: Refactors deployment bootstrap into separate configuration and startup stages while recording richer active-deployment state.

Changes:

  • Introduces deploy.Configure for prerequisites, bundle generation, OpenBao setup, and secret resolution.
  • Introduces deploy.Up for target-aware service startup, readiness checks, and VPS confirmation.
  • Replaces the legacy version marker with backward-compatible state.json and timestamped bundle directories.
  • Adds OpenBao AppRole credential storage plus versola secrets login and secrets test commands.
  • Extracts shared Docker command execution and updates uninstall cleanup for active state and OpenBao volumes.
  • Extends local port checks to tolerate the deployment's existing nginx container during redeploys.

Technical Notes: Generated secrets are resolved from OpenBao before Compose runs, and local/VPS startup paths select different service sets while preserving legacy state readability.

🤖 Was this summary useful? React with 👍 or 👎

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 1 suggestion posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread internal/state/state.go Outdated
@BKJN1

BKJN1 commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator Author

augment review

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. No suggestions at this time.

Comment augment review to trigger a new review at any time.

* deploy: create the external openbao-file volume before compose up

* secrets: OpenBao AppRole client + secrets login/test commands

* deploy: resolve auth/central/edge secrets against OpenBao before starting the stack

* feat: support vps target in configure/up (TARGET passthrough, confirmation before touching prod)

* fix: stable compose project name across configure runs (was failing on redeploy)

* fix: validate target in openbao credentials path, remove OpenBao volume on local uninstall

* fix: uninstall only clears ~/.versola/active (was wiping all targets' OpenBao credentials)

* fix: prompt for OpenBao secret-id instead of passing it as an arg; PortFree does a raw bind check even for our own container

* fix: stop echoing vps admin password on every deploy; preserve deployment state across a failed redeploy; don't drop unknown OpenBao keys on write; prompt for secret-id instead of passing it as an arg; raw bind check for our own container's port

* fix: don't over-check own container's port on native Docker; clean up orphaned OpenBao container on uninstall; fix stale secrets-login usage hint

* fix: mask secret-id input at the terminal (was visible in scrollback/session recordings)

* fix: write state.json atomically (was truncate-then-write); remove generated-secrets.env candidates after resolving (world-readable, held real secret material)

* fix: restrict generated-secrets.env permissions immediately, not only after successful resolve

* fix: don't abort configure when chmod on generated-secrets.env fails (root-owned files on Linux VPS)
@BKJN1

BKJN1 commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator Author

augment review

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 3 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread internal/deploy/configure.go
func restrictGeneratedSecretsPerms(dir string) {
for _, service := range secretServices {
path := filepath.Join(dir, service+".generated-secrets.env")
if err := os.Chmod(path, 0o600); err != nil {

@augmentcode augmentcode Bot Aug 15, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

internal/deploy/secrets.go:44: On Linux, the tools container normally writes these files as root, so this chmod failure is expected; because Prepare creates a mode-0755 bundle directory, their usual 0644 mode leaves generated passwords readable to every local user. A failing configuration, including the documented initial VPS path, then leaves the candidate files exposed indefinitely.

Severity: high

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Comment thread internal/deploy/up.go
…-exposure gap chmod couldn't (root-owned files on Linux)
@BKJN1

BKJN1 commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator Author

augment review

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 1 suggestion posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread internal/cmd/uninstall.go
// etc.) -- deleting those should be a deliberate decision someone
// makes on purpose, not a side effect of running this general
// cleanup command against the wrong target by mistake.
if target == "local" {

@augmentcode augmentcode Bot Aug 15, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

target only reflects the last configured bundle, not every namespace retained in this shared volume. After a VPS deployment is reconfigured to local, this branch removes versola-openbao-file and destroys the still-retained versola/vps/* production secrets; could we avoid treating the shared volume as local-only?

Severity: high

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant